<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AI 对话</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="h-screen bg-gray-50 flex">

<!-- 左侧聊天列表 -->
<aside class="w-64 bg-white shadow flex flex-col">
    <div class="p-4 border-b">
        <button id="newChatBtn" class="w-full bg-blue-600 text-white py-2 rounded hover:bg-blue-700">新建聊天</button>
    </div>
    <ul id="chatList" class="flex-1 overflow-y-auto p-2 space-y-2"></ul>
</aside>

<!-- 右侧对话区 -->
<main class="flex-1 flex flex-col">
    <!-- 头部 -->
    <header class="bg-white border-b px-6 py-4 flex items-center justify-between">
        <h1 id="currentTitle" class="text-lg font-semibold text-gray-800">请选择一个聊天</h1>
        <div id="chatOps" class="hidden space-x-2">
            <button id="renameBtn" class="text-sm px-3 py-1 rounded bg-gray-200 hover:bg-gray-300">重命名</button>
            <button id="deleteBtn" class="text-sm px-3 py-1 rounded bg-red-500 text-white hover:bg-red-600">删除</button>
        </div>
    </header>

    <!-- 消息区 -->
    <section id="messageList" class="flex-1 overflow-y-auto p-4 space-y-3"></section>

    <!-- 输入区 -->
    <footer class="bg-white border-t p-4">
        <div class="flex items-end gap-2">
        <textarea id="messageInput" rows="2" placeholder="输入消息（Shift+Enter 换行）"
                  class="flex-1 resize-none border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
                  disabled></textarea>
            <input id="imageInput" type="file" accept="image/*" class="hidden" />
            <button id="imageBtn" class="px-3 py-2 bg-gray-200 rounded-lg hover:bg-gray-300" disabled>📷</button>
            <button id="sendBtn" class="px-5 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700" disabled>发送</button>
        </div>
    </footer>
</main>

<script>
    /**************** 数据层 ****************/
    const STORAGE_KEY = 'aiChats';
    let chats = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
    let currentChatId = null;
    let eventSource = null;

    /**************** DOM ****************/
    const $ = id => document.getElementById(id);
    const newChatBtn = $('newChatBtn');
    const chatList = $('chatList');
    const currentTitle = $('currentTitle');
    const chatOps = $('chatOps');
    const messageList = $('messageList');
    const messageInput = $('messageInput');
    const imageInput = $('imageInput');
    const imageBtn = $('imageBtn');
    const sendBtn = $('sendBtn');
    const renameBtn = $('renameBtn');
    const deleteBtn = $('deleteBtn');

    /**************** 初始化 ****************/
    init();
    function init() {
        renderChatList();
        bindEvents();
    }

    /**************** 事件绑定 ****************/
    function bindEvents() {
        newChatBtn.onclick = createChat;
        sendBtn.onclick = () => send();
        renameBtn.onclick = renameChat;
        deleteBtn.onclick = deleteChat;
        imageBtn.onclick = () => imageInput.click();
        messageInput.onkeydown = e => {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                send();
            }
        };
        imageInput.onchange = e => {
            if (e.target.files[0]) imageBtn.textContent = '📷✅';
        };
    }

    /**************** 聊天列表 ****************/
    function createChat() {
        const chat = {
            id: Date.now(),
            title: `聊天 ${chats.length + 1}`,
            messages: [],
            createdAt: new Date().toISOString()
        };
        chats.unshift(chat);
        save();
        renderChatList();
        selectChat(chat.id);
    }

    function renderChatList() {
        chatList.innerHTML = '';
        chats.forEach(c => {
            const li = document.createElement('li');
            li.className = `p-3 rounded cursor-pointer hover:bg-gray-100 ${c.id === currentChatId ? 'bg-blue-50 border-l-4 border-blue-600' : ''}`;
            li.innerHTML = `<div class="text-gray-800 truncate">${c.title}</div>`;
            li.onclick = () => selectChat(c.id);
            chatList.appendChild(li);
        });
    }

    function selectChat(id) {
        currentChatId = id;
        const chat = chats.find(c => c.id === id);
        if (!chat) return;
        currentTitle.textContent = chat.title;
        chatOps.classList.remove('hidden');
        [messageInput, sendBtn, imageBtn].forEach(el => el.disabled = false);
        renderMessages(chat.messages);
    }

    /**************** 消息渲染 ****************/
    function renderMessages(msgs) {
        messageList.innerHTML = '';
        msgs.forEach(m => {
            const div = document.createElement('div');
            div.className = `flex ${m.role === 'user' ? 'justify-end' : 'justify-start'}`;
            div.innerHTML = `
          <div class="max-w-md px-4 py-2 rounded-lg ${m.role === 'user' ? 'bg-blue-600 text-white' : 'bg-gray-200 text-gray-800'}">
            ${m.image ? `<img src="${m.image}" class="rounded mb-2 max-h-48"/>` : ''}
            <div class="whitespace-pre-wrap">${m.content}</div>
          </div>`;
            messageList.appendChild(div);
        });
        messageList.scrollTop = messageList.scrollHeight;
    }

    /**************** 发送消息 ****************/
    function send() {
        const text = messageInput.value.trim();
        const file = imageInput.files[0];
        if (!text && !file) return;

        const chat = chats.find(c => c.id === currentChatId);
        if (!chat) return;

        // 用户消息
        const userMsg = { role: 'user', content: text, timestamp: new Date().toISOString() };
        if (file) {
            const reader = new FileReader();
            reader.onload = e => {
                userMsg.image = e.target.result;
                pushMsg(chat, userMsg);
                doStream(chat, text, file);
            };
            reader.readAsDataURL(file);
        } else {
            pushMsg(chat, userMsg);
            doStream(chat, text, null);
        }

        // 清空输入
        messageInput.value = '';
        imageInput.value = '';
        imageBtn.textContent = '📷';
    }

    function pushMsg(chat, msg) {
        chat.messages.push(msg);
        save();
        renderMessages(chat.messages);
    }

    /**************** 流式请求 ****************/
    function doStream(chat, text, imageFile) {
        // AI 占位
        const aiMsg = { role: 'assistant', content: '', timestamp: new Date().toISOString() };
        pushMsg(chat, aiMsg);

        // 构造带查询参数的 GET 流式地址
        const url = new URL('http://localhost:8080/api/ai/chat-image', location.origin);
        url.searchParams.set('text', text);
        if (imageFile) {
            // 简易处理：前端把图片转 base64 后直接拼到 text 中，后端仍复用原逻辑
            const reader = new FileReader();
            reader.onload = () => {
                url.searchParams.set('text', text + '\n\n![img](' + reader.result + ')');
                connect(url, chat, aiMsg);
            };
            reader.readAsDataURL(imageFile);
        } else {
            connect(url, chat, aiMsg);
        }
    }

    function connect(url, chat, aiMsg) {
        if (eventSource) eventSource.close();
        eventSource = new EventSource(url);

        eventSource.onmessage = ev => {
            try {
                const res = JSON.parse(ev.data);
                if (res.output && typeof res.output.content === 'string') aiMsg.content += res.output.content;
                if (res.metadata && res.metadata.finishReason === 'STOP') {
                    eventSource.close();
                    eventSource = null;
                }
            } catch (_) {
                // 非 JSON 直接拼内容
                aiMsg.content += ev.data;
            }
            renderMessages(chat.messages);
        };

        eventSource.onerror = () => {
            aiMsg.content += '\n[流结束]';
            renderMessages(chat.messages);
            save();
            if (eventSource) eventSource.close();
            eventSource = null;
        };
    }

    /**************** 重命名 / 删除 ****************/
    function renameChat() {
        const chat = chats.find(c => c.id === currentChatId);
        if (!chat) return;
        const t = prompt('新名称', chat.title);
        if (t) {
            chat.title = t;
            save();
            currentTitle.textContent = t;
            renderChatList();
        }
    }

    function deleteChat() {
        if (!confirm('确定删除当前聊天？')) return;
        chats = chats.filter(c => c.id !== currentChatId);
        save();
        currentChatId = null;
        currentTitle.textContent = '请选择一个聊天';
        chatOps.classList.add('hidden');
        messageList.innerHTML = '';
        [messageInput, sendBtn, imageBtn].forEach(el => el.disabled = true);
        renderChatList();
    }

    /**************** 存储 ****************/
    function save() {
        localStorage.setItem(STORAGE_KEY, JSON.stringify(chats));
    }
</script>
</body>
</html>